Many different types of mechanical systems include components that are configured to move within the system. For example, in a tape library system (discussed in further detail below), one or more robot arms may be configured to operate along a particular rail. Other examples of components that may be configured to move within a system include doors (which may open and close), storage slots (which may accept and eject storage media), or any other type of component with movable physical parts. Some components may require manual manipulation (i.e., by a human operator) to be moved. Other components may be movable under control of one or more computer processors.
In computer systems, a process may be performed synchronously or asynchronously. In synchronous processing, an execution thread persists throughout the process, from start to finish. All tasks that make up the process are considered a single unit, which either fails or succeeds in its entirety. That is, the persistent execution thread fails and therefore the entire process fails. If the execution thread (the “primary thread”) communicates with another execution thread (a “secondary thread”), the primary thread must wait for a response from the secondary thread before continuing the process.
For example, consider a synchronous process for preparing breakfast cereal, with the individual preparing the breakfast cereal conceptualized as the primary execution thread. The primary thread may prepare the breakfast cereal by performing the following tasks, in sequence: taking a cereal box from a cupboard; taking a milk jug from the refrigerator; taking a bowl from a drawer; taking a spoon from another drawer; pouring cereal from the box into the bowl; pouring milk from the jug into the bowl; placing the spoon into the bowl; returning the cereal box to the cupboard; and returning the milk to the refrigerator. The primary thread may enlist a secondary thread to perform one or more of these steps. For example, the primary thread may ask a secondary thread to fetch the spoon. However, the primary thread cannot perform other tasks while it waits for the secondary thread to complete its task(s). In addition, if any of the tasks fails (for example, if the primary thread spills the milk or the secondary thread fails to locate a spoon), then the entire process fails; the breakfast cereal is not prepared.
In asynchronous processing, two or more tasks within a process are completed independently of each other. For example, one execution thread may perform a subset of the tasks and another execution thread may perform another subset of the tasks. If one execution thread delegates a task to another execution thread, the delegating thread may continue executing even as the delegate performs its task. In the breakfast cereal example above, one thread may pour the milk at the same time that another thread returns the box of cereal to the cupboard. In addition, if an execution thread fails, the process may be able to continue using other execution threads. In the breakfast cereal example above, if one thread fails while attempting to obtain the milk jug, another thread may be able to remedy from the failure. Yet another thread may be able to perform another task (e.g., obtaining a spoon) while the failure is being remedied. In other words, in asynchronous processing, the entire process may not be required to succeed or fail as a unit. Thus, asynchronous processing may improve system reliability by allowing a process to continue even if a particular execution thread fails. Alternatively or in addition, asynchronous processing may allow for faster processing, due to parallelism of multiple execution threads.
The approaches described in this section are approaches that could be pursued, but not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated, it should not be assumed that any of the approaches described in this section qualify as prior art merely by virtue of their inclusion in this section.